<template>
  <el-card class="global-card">
    <template #header>
      <div class="card-header">
        <span>商品列表</span>
        <el-button type="primary" :icon="Plus" @click="handleClickAdd"
          >添加</el-button
        >
      </div>
    </template>
    <AsideSearch
      :is-loading="loadOpts.refresh"
      @on-search="handleClickSearch"
    />
    <el-table
      :data="tableData"
      style="width: 100%; margin: 20px 0"
      border
      highlight-current-row
    >
      <!-- <el-table-column prop="id" label="#ID" min-width="56"></el-table-column> -->
      <el-table-column
        prop="sort"
        label="排序"
        min-width="56"
      ></el-table-column>
      <el-table-column label="商品信息" min-width="320">
        <template #default="scope">
          <div style="display: flex; align-items: center">
            <PipeImage :url="scope.row.cover" />
            <div style="flex: 1; padding-left: 8px">
              <div style="line-height: normal; margin-bottom: 8px">
                {{ scope.row.title }}
              </div>
              <PipeTags type="goods-type" :state="scope.row.type" />
              <el-tag
                type="info"
                effect="plain"
                v-if="scope.row.category"
                style="margin-left: 8px"
              >
                {{ scope.row.category?.title }}
              </el-tag>
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="商品价格" min-width="96">
        <template #default="scope">
          <PipeMoney :type="scope.row.type" :money="scope.row.price" />
        </template>
      </el-table-column>
      <el-table-column
        prop="stock"
        label="库存量"
        min-width="80"
      ></el-table-column>
      <el-table-column label="多规格" min-width="128">
        <template #default="scope">
          <div
            v-for="(item, index) in formatGoodsSpecs(scope.row.specs)"
            :key="index"
          >
            {{ item.title }}:{{ item.list }}
          </div>
        </template>
      </el-table-column>
      <el-table-column label="上架" min-width="64">
        <template #default="scope">
          <el-switch
            v-model="scope.row.state"
            :active-value="1"
            :inactive-value="0"
            active-color="#13ce66"
            inactive-color="#ff4949"
            :loading="loadOpts.submit"
            :before-change="handleToggleSwitch.bind(null, scope.row, 'state')"
          />
        </template>
      </el-table-column>
      <el-table-column prop="state" label="营销" min-width="192">
        <template #default="scope">
          <el-tag type="info" effect="plain" v-if="scope.row.isRef"
            >推荐</el-tag
          >
          <el-tag
            type="info"
            effect="plain"
            v-if="scope.row.isNew"
            style="margin-left: 8px"
            >新品</el-tag
          >
          <el-tag
            type="info"
            effect="plain"
            v-if="scope.row.isHot"
            style="margin-left: 8px"
            >热卖</el-tag
          >
          <el-tag
            type="info"
            effect="plain"
            v-if="scope.row.isPostage"
            style="margin-left: 8px"
            >包邮</el-tag
          >
          <el-tag
            type="info"
            effect="plain"
            v-if="scope.row.isReturn"
            style="margin-left: 8px"
            >支持退货</el-tag
          >
        </template>
      </el-table-column>
      <!-- <el-table-column label="创建时间" min-width="192">
        <template #default="scope">
          <PipeDatetime :value="scope.row.createTime" />
        </template>
      </el-table-column> -->
      <el-table-column fixed="right" label="操作" width="144">
        <template #default="scope">
          <el-button
            size="small"
            type="primary"
            link
            :icon="Edit"
            @click="handleClickRowEdit(scope.row)"
            >编辑</el-button
          >
          <el-popconfirm
            :title="
              stateName === 'recycle'
                ? '是否还原此商品？'
                : '是否删除到回收站？'
            "
            confirm-button-text="确定"
            cancel-button-text="取消"
            :icon="InfoFilled"
            icon-color="red"
            :hide-after="0"
            @confirm="handleClickRowDel(scope.row)"
          >
            <template #reference>
              <el-button
                size="small"
                type="primary"
                link
                :icon="stateName === 'recycle' ? Box : Delete"
                >{{ stateName === 'recycle' ? '还原' : '删除' }}</el-button
              >
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      v-model:currentPage="pageOpts.page.value"
      :page-sizes="pageOpts.sizes.value"
      :page-size="pageOpts.size.value"
      :layout="pageOpts.layout.value"
      :total="pageOpts.total.value"
      small
      background
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    ></el-pagination>
  </el-card>

  <DrawerForm
    v-model="drawerOpts.visible"
    :title="drawerOpts.title"
    :size="drawerOpts.size"
    :is-edit="drawerOpts.isEdit"
    :row-data="drawerOpts.data"
    @on-refresh="requestData"
  />
</template>

<script setup lang="ts">
import { Edit, Plus, InfoFilled, Delete, Box } from '@element-plus/icons-vue';
import { provide, reactive, ref } from 'vue';

import { getGoodsList, updateSwitch } from '@/apis/goods';
import DrawerForm from './form.vue';
import { ElMessage } from 'element-plus';
import { InitDrawerOpts, InitLoadOpts, InitPageOpts } from '@/utils/common';
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
import { getGoodsCategoryTree } from '@/apis/goods-category';
import AsideSearch from './aside-search.vue';

// [在售|待售|回收站]
type StateName = 'sale' | 'out' | 'recycle';
const route = useRoute();
const stateName = ref(route.params.name as StateName);

// 加载状态
const loadOpts = reactive(InitLoadOpts());

// 查询数据
let searchData: any;
const handleClickSearch = (data: any) => {
  searchData = data;
  requestData();
};

// 列表数据
let tableData = ref<API.goods.TableData[]>();

// 分页数据
const pageOpts = InitPageOpts({
  page: 1,
  size: 10
});

// 抽屉
const drawerOpts = reactive(
  InitDrawerOpts<API.goods.TableData | any>({ size: '88%' })
);

// 切换显示条数
const handleSizeChange = (size: number) => {
  pageOpts.size.value = size;
  pageOpts.page.value = 1;
  requestData();
};

// 切换页数
const handleCurrentChange = (page: number) => {
  pageOpts.page.value = page;
  requestData();
};

// 切换状态
const handleToggleSwitch = async (
  item: API.goods.EntitySchema,
  field: keyof API.goods.EntitySchema
): Promise<any> => {
  loadOpts.submit = true;
  try {
    const res = await updateSwitch(item.ownId!, {
      [field]: +!item[field]
    });
    loadOpts.submit = false;
    ElMessage.success(res.message);
    return Promise.resolve(true);
  } catch (err: any) {
    loadOpts.submit = false;
    return Promise.reject(new Error('Error'));
  }
};

// 添加
const handleClickAdd = () => {
  drawerOpts.title = '添加';
  drawerOpts.isEdit = false;
  drawerOpts.data = {};
  drawerOpts.visible = !drawerOpts.visible;
};

// 编辑
const handleClickRowEdit = (row: API.goods.EntitySchema) => {
  drawerOpts.title = '编辑';
  drawerOpts.isEdit = true;
  drawerOpts.data = row;
  drawerOpts.visible = true;
};

// 删除
const handleClickRowDel = (row: API.goods.EntitySchema) => {
  if (loadOpts.submit) return;
  loadOpts.submit = true;

  handleToggleSwitch(row, 'isDel')
    .then(() => {
      loadOpts.submit = false;
      // 重新刷新数据
      requestData();
    })
    .catch((err) => {
      loadOpts.submit = false;
      ElMessage.error(err.message);
    });
};

// 商品分类列表
const categoryTree = ref<API.goodsCategory.TreeSchema[]>([]);
provide('categoryTree', categoryTree);
const requestCategoryTree = () => {
  getGoodsCategoryTree()
    .then((res) => {
      categoryTree.value = res.data;
    })
    .catch((err) => {
      console.log('table list error', err);
    });
};
requestCategoryTree();

// 解析多规格的json字符串
const formatGoodsSpecs = (
  specs: string
): { title: string; list: string[] }[] => {
  if (!specs) return [];

  try {
    const list = JSON.parse(specs);
    return list;
  } catch (error) {
    return [];
  }
};

// 获取分页数据
const requestData = () => {
  const dataOpt = {
    field: 'more',
    page: pageOpts.page.value,
    limit: pageOpts.size.value,
    state: stateName.value,

    ...searchData
  };

  // 开始加载
  loadOpts.refresh = true;

  getGoodsList(dataOpt)
    .then((res) => {
      tableData.value = res.data.data || [];
      pageOpts.total.value = res.data.total;

      // 加载结束
      loadOpts.refresh = false;
    })
    .catch((err) => {
      console.log('table list error', err);
      // 加载结束
      loadOpts.refresh = false;
    });
};

// 监听组件复用
onBeforeRouteUpdate((to) => {
  stateName.value = to.params.name as StateName;
  requestData();
});

requestData();
</script>

<style lang="scss" scoped>
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
